/**
 * 常用的方式有typeof
 * 他可以判断基本类型，但是不能判断数组和对象
 * 给出的都是object，然偶就是null,也给识别
 * 成了对象
 */

let a = "1";

let b = 1;

let c = [1, 3, 5];

let d = {
  a: "1",
  b: "2",
};

let e = Symbol();

let f = function () {
  console.log("123");
};

// console.log(typeof a);
// console.log(typeof b);
// console.log(typeof c);
// console.log(typeof d);
// console.log(typeof e);
// console.log(typeof f);
// console.log(typeof undefined);
// console.log(typeof null);

/**
 * 第二种方式就是Object.prototype.toString.call
 * 这个可以完美的识别所有类型
 * 只是打印出来的类型格式稍微有些问题，可以自己处理一下
 */
console.log(Object.prototype.toString.call(a));
console.log(Object.prototype.toString.call(b));
console.log(Object.prototype.toString.call(c));
console.log(Object.prototype.toString.call(d));
console.log(Object.prototype.toString.call(e));
console.log(Object.prototype.toString.call(f));
console.log(Object.prototype.toString.call(undefined));
console.log(Object.prototype.toString.call(null));

const isTypeOf = (data) => {
  return Object.prototype.toString
    .call(data)
    .replace(/\[object (\w+)\]/, "$1")
    .toLowerCase();
};

console.log(isTypeOf(a));
console.log(isTypeOf(b));
console.log(isTypeOf(c));
console.log(isTypeOf(d));
console.log(isTypeOf(e));
console.log(isTypeOf(f));
console.log(isTypeOf(undefined));
console.log(isTypeOf(null));

let map = new Map();
map.set("name", "tom");
map.set("name", "jack");
for (const [key, value] of map) {
  console.log(`${key} = ${value}`);
}

console.log(isTypeOf(map));

/**
 * 判断obj是否为空
 * @param obj
 * @returns {boolean}
 */
const isEmpty = (obj) => {
  if (typeof obj === "undefined" || obj === null) {
    return true;
  } else {
    if (typeof obj === "string" && obj.trim() === "") {
      return true;
    } else if (obj instanceof Object && Object.keys(obj).length === 0) {
      return true;
      // obj instanceof Array 没有 Array.isArray(obj) 严谨
    } else if (Array.isArray(obj) && obj.length === 0) {
      return true;
    }
    return false;
  }
};

let a1 = { a: "" };
console.log("123", isEmpty(a1));

// 对于上面的方法，lodash中有类似的方法isEmpty
// 它对于数组，对象，字符串是否为空都能正确检测
// 但是如果一个对象是有属性名，但是属性值是空的，那它是不能检测的
// 跟上面的这个方法的效果是一致的

/**
 * 去除对象中的空属性
 * @param obj
 */
const removePropertyOfNull = (obj) => {
  Object.keys(obj).forEach((item) => {
    if (!obj[item] && obj[item] !== 0) delete obj[item];
  });
  return obj;
};
